#include <iostream>
#include <string>
#include <memory>
#include <sstream>
#include <jsoncpp/json/json.h> //Jsoncpp头文件

using namespace std;

//实现数据序列化的Json格式
bool serialize(const Json::Value& value, string& body) {
    stringstream ss;
    Json::StreamWriterBuilder build;
    //注意：若这里使用普通指针指向开辟的空间，最后需要用delete释放该空间，如下
    //Json::StreamWriter* writer = build.newStreamWriter();
    //delete writer; 
    
    // 为了保险起见，这里最好使用智能指针
    unique_ptr<Json::StreamWriter> writer(build.newStreamWriter());
    int n = writer->write(value, &ss);
    if (n != 0)
    {
        cout << "Json serialize failed" << endl;
        return false;
    }
    body = ss.str();
    return true;
}

//实现Json字符串的反序列化
bool unserialize(const string& body, Json::Value& value) {
    Json::CharReaderBuilder build;
    string errs;
    unique_ptr<Json::CharReader> reader(build.newCharReader());
    bool n = reader->parse(body.c_str(), body.c_str() + body.size(), &value, &errs);
    if (n == false)
    {
        cout << "Json unserialize failed" << endl;
        return false;
    }
    return true;
}

int main()
{
    // C/C++表示
    const char* name = "小明";
    int age = 18;
    const char* sex = "男";
    double score[3] = { 88, 77.5, 66 }; 
    
    // Json表示
    Json::Value student;
    student["姓名"] = "小明";
    student["年龄"] = 18;
    student["性别"] = "男";
    student["成绩"].append(score[0]);
    student["成绩"].append(score[1]);
    student["成绩"].append(score[2]);
    
    // 在对象中嵌套数据对象
    Json::Value f, g1, g2;
    f["书籍"] = "西游记";
    f["运动"] = "打篮球";
    g1["苹果"] = "a";
    g1["安卓"] = "b";
    g2["Linux"] = "c";
    g2["Windows"] = "d";
    f["系统"].append(g1);
    f["系统"].append(g2);
    student["爱好"] = f;

    // 将数据序列化为Json格式，并将其放入到body变量中
    cout << "数据Json格式的序列化: " << endl;
    string body;
    serialize(student, body);
    cout << body << endl;
    
    // 将数据反序列化，并将其存储在Value对象中
    cout << "数据Json格式的反序列化: " << endl;
    Json::Value value;
    bool n = unserialize(body, value);
    if (n == false) exit(-1);
    cout << "姓名: " << value["姓名"].asString() << endl;
    cout << "年龄: " << value["年龄"].asInt() << endl;
    cout << "性别: " << value["性别"].asString() << endl;
    for (int i = 0; i < value["成绩"].size(); i++)
    {
        cout << "成绩: " << value["成绩"][i].asDouble() << " ";
    }
    cout << endl;
    cout << "爱好:\n    ";
    cout << "书籍: " << value["爱好"]["书籍"].asString() << "\n    ";
    cout << "系统: " << "安卓:" << value["爱好"]["系统"][0]["安卓"].asString() << " ";
    cout << "苹果:" << value["爱好"]["系统"][0]["苹果"].asString() << " ";
    cout << "Linux:" << value["爱好"]["系统"][1]["Linux"].asString() << " ";
    cout << "Windows:" << value["爱好"]["系统"][1]["Windows"].asString() << "\n    ";
    cout << "运动: " << value["爱好"]["运动"].asString() << endl;
    return 0;
}

